﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Casamiel.Domain;
using Casamiel.Domain.Entity;

using Dapper;
using Smooth.IoC.UnitOfWork.Interfaces;

namespace Casamiel.Infrastructure.Repositories
{
    /// <summary>
    /// Invoice detail repository.
    /// </summary>
    public sealed class InvoiceDetailRepository : BaseRepository<InvoiceDetail, long>, IInvoiceDetailRepository
    {
        /// <summary>
        /// Initializes a new instance of the
        /// <see cref="T:Casamiel.Infrastructure.Repositories.InvoiceDetailRepository"/> class.
        /// </summary>
        /// <param name="factory">Factory.</param>
        public InvoiceDetailRepository(IDbFactory factory) : base(factory)
        {

        }
        /// <summary>
        /// Updates the by list async.
        /// </summary>
        /// <returns>The by list async.</returns>
        /// <param name="list">List.</param>
        /// <param name="uow">Uow.</param>
        public async Task UpdateByListAsync(List<InvoiceDetail> list, IUnitOfWork uow)
        {
			if (uow is null) {
				throw new ArgumentNullException(nameof(uow));
			}

			var sql = $"update  {Sql.Table<InvoiceDetail>(uow.SqlDialect)} set Invoice_ID=@Invoice_ID, Status=@Status,UpdateTime=@UpdateTime where ID=@ID";
			
			await uow.Connection.ExecuteAsync(sql.CheckSafeSql(), list, uow.Transaction).ConfigureAwait(true);
        }
        /// <summary>
        /// Gets for KBA sync.
        /// </summary>
        /// <returns>The for KBA sync.</returns>
        /// <param name="Ids">Identifiers.</param>
        /// <typeparam name="TSession">The 1st type parameter.</typeparam>
        public async Task<List<InvoiceDetail>> GetListAsync<TSession>(string Ids,string Mobile) where TSession : class, ISession
        {
			if (Ids is null) {
				throw new ArgumentNullException(nameof(Ids));
			}

			string[] a = Ids.Split(',');
            using (var session = Factory.Create<TSession>())
            {
                var list = await session
                    .QueryAsync<InvoiceDetail>($"SELECT * FROM {Sql.Table<InvoiceDetail>(session.SqlDialect)} where  Status=1 and ID in @ids and Mobile=@Mobile", new { ids = a,Mobile })
                    .ConfigureAwait(false);
                return list.ToList();
            }
        }

        /// <summary>
        /// Gets the list by invoice IDA sync.
        /// </summary>
        /// <returns>The list by invoice IDA sync.</returns>
        /// <param name="InvoiceID">Invoice identifier.</param>
        /// <param name="Mobile">Mobile.</param>
        /// <typeparam name="TSession">The 1st type parameter.</typeparam>
        public async Task<List<InvoiceDetail>> GetListAsync<TSession>(long InvoiceID, string Mobile) where TSession : class, ISession
        {
            using (var session = Factory.Create<TSession>())
            {
                var list = await session.Connection
                    .QueryAsync<InvoiceDetail>($"SELECT * FROM {Sql.Table<InvoiceDetail>(session.SqlDialect)} where Invoice_ID=@InvoiceID", new { InvoiceID })
                    .ConfigureAwait(false);
                return list.ToList();
            }
        }

		/// <summary>
		/// 
		/// </summary>
		/// <typeparam name="TSession"></typeparam>
		/// <param name="OutTradeNO"></param>
		/// <returns></returns>
		public async Task<InvoiceDetail> FindByOutTradeNOAsync<TSession>(string OutTradeNO) where TSession : class, ISession
		{
			using (var session = Factory.Create<TSession>()) {
				var entity = await session.Connection
					.QueryFirstOrDefaultAsync<InvoiceDetail>($"SELECT * FROM {Sql.Table<InvoiceDetail>(session.SqlDialect)} where OutTradeNO=@OutTradeNO", new { OutTradeNO })
					.ConfigureAwait(false);
				return entity;
			}
		}
		/// <summary>
		/// Gets the list by mobile date time async.
		/// </summary>
		/// <returns>The list by mobile date time async.</returns>
		/// <param name="Mobile">Mobile.</param>
		/// <param name="dt">Dt.</param>
		/// <param name="pageIndex">Page index.</param>
		/// <param name="pageSize">Page size.</param>
		/// <typeparam name="TSession">The 1st type parameter.</typeparam>
		public async Task<PagingResult<InvoiceDetail>> GetListAsync<TSession>(string Mobile, DateTime dt, int pageIndex, int pageSize) where TSession : class, ISession
        {
            var CreateTime = dt.ToString("yyyy-MM-dd HH:mm:ss",System.Globalization.CultureInfo.CurrentCulture);
            PagingResult<InvoiceDetail> result = new PagingResult<InvoiceDetail>
            {
                PageIndex = pageIndex,
                PageSize = pageSize
            };
            using (var session = Factory.Create<TSession>())
            {
                var sql = GetSelectSQL($"{Sql.Table<InvoiceDetail>(session.SqlDialect)}", $" Mobile=@Mobile  and CreateTime >@CreateTime and status=1", "ID desc", pageIndex, pageSize);
				string countsql = $"select count(*) from  {Sql.Table<InvoiceDetail>(session.SqlDialect)} where Mobile=@Mobile  and CreateTime >@CreateTime and status=1";
                int total = 0;
                total = await session.Connection.QueryFirstAsync<int>(countsql,new  { Mobile,CreateTime}).ConfigureAwait(false);
                var list = await session.QueryAsync<InvoiceDetail>(sql.Item1,new { begin = sql.Item2, end = sql.Item3, Mobile, CreateTime }).ConfigureAwait(false);
                result.Data = list.ToList();
                result.Total = total;
                return result;
                //var list = await session.Connection.QueryAsync<InvoiceDetail>($"SELECT * FROM {Sql.Table<InvoiceDetail>(session.SqlDialect)} where Mobile=@Mobile and CreateTime>@CreateTime", new { Mobile, CreateTime });
                //return list.ToList();
            }
        }
    }
}
